import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.mongodb.MongoClient;
import com.mongodb.MongoException;
import com.mongodb.WriteConcern;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.DBCursor;
import com.mongodb.ServerAddress;

public class MongoTunnedTemplate extends Template {
	private MongoClient client;
	@Override
	public void configure(Map<String, Object> params) {

		try {
			client = new MongoClient();
		} catch (UnknownHostException e) {
			
		}
	}

	@Override
	public Map<String, Object> insertLineItems(int nInsertsLineItem) {
		int nInsertsLineitemRegs = 0;
		DB oDb = client.getDB("cbde");
		DBCollection oCollection = oDb.getCollection("lineitem");
		Map<String, Object> result = new HashMap<String, Object>();
		
		calculateInsertsExpected(nInsertsLineItem);
		List<BasicDBObject> aOrders = _getOrders();
		
		for (int i = 0; i < nInsertsLineItem; i++) {
			BasicDBObject oDocument = new BasicDBObject(
							"l_order", 			aOrders.get(i % nInsertsOrdersExpected)).
                    append(	"l_partkey", 		RandomValues.randomInt(1000, 9999)).
                    append(	"l_suppkey", 		RandomValues.randomInt(1000, 9999)).
                    append(	"l_linenumber",		RandomValues.randomInt(1000, 9999)).
                    append(	"l_quantity", 		RandomValues.randomFloat(1000, 9999, 2)).
                    append(	"l_extendedprice", 	RandomValues.randomFloat(1000, 9999, 2)).
                    append(	"l_discount", 		RandomValues.randomFloat(1000, 9999, 2)).
                    append(	"l_tax",			RandomValues.randomFloat(1000, 9999, 2)).
                    append(	"l_returnflag",		RandomValues.randomString(1)).
                    append(	"l_linestatus",		RandomValues.randomString(1)).
                    append(	"l_shipdate",		RandomValues.randomDate().toString()).
                    append(	"l_commitdate",		RandomValues.randomDate().toString()).
                    append(	"l_receiptdate",	RandomValues.randomDate().toString()).
                    append(	"l_shipinstruct",	RandomValues.randomString(25)).
                    append(	"l_shipmode",		RandomValues.randomString(10)).
                    append(	"l_comment",		RandomValues.randomString(44));
			oCollection.insert(oDocument);
			if (i % 100 == 0)
			System.out.println("Insertados " + i + " de " + nInsertsLineItem + " lineitems");
			nInsertsLineitemRegs++;
		}
		result.put("lineitemRegs", nInsertsLineitemRegs);
		return result;
	}

	@Override
	public int query1() {
		return 0;
		// TODO Auto-generated method stub

	}

	@Override
	public int query2() {
		return 0;
		// TODO Auto-generated method stub

	}

	@Override
	public int query3() {
		return 0;
		// TODO Auto-generated method stub

	}

	@Override
	public int query4() {
		return 0;
		// TODO Auto-generated method stub

	}

	@Override
	public int deleteData() {
		DB oDb = client.getDB("cbde");
		if (oDb != null) {
			client.dropDatabase("cbde");
		}
		return 0;
	}

	@Override
	public void getDataForQueries() {
		// TODO Auto-generated method stub
		
	}
	
	private List<BasicDBObject> _getOrders() {
		List<BasicDBObject> aOrders = new ArrayList<BasicDBObject>();
		List<BasicDBObject> aCustomers = _getCustomers();
		/*O_ORDERKEY Identifier SF*1,500,000 are sparsely populated
		O_CUSTKEY Identifier Foreign Key to C_CUSTKEY
		O_ORDERSTATUS fixed text, size 1
		O_TOTALPRICE Decimal
		O_ORDERDATE Date
		O_ORDERPRIORITY fixed text, size 15
		O_CLERK fixed text, size 15
		O_SHIPPRIORITY Integer
		O_COMMENT variable text, size 79*/
		for (int i = 0; i < this.nInsertsOrdersExpected; i++) {
			BasicDBObject oDocument = new BasicDBObject(
					"o_orderkey", 			i + 1).
            append(	"o_customer", 			aCustomers.get(i % nInsertsCustomerExpected)).
            append(	"o_orderstatus", 		RandomValues.randomString(1)).
            append(	"o_totalprice",			RandomValues.randomFloat(1000, 1200, 2)).
            append(	"o_orderdate", 			RandomValues.randomDate()).
            append(	"o_orderpriority", 		RandomValues.randomString(15)).
            append(	"o_clerk", 				RandomValues.randomString(15)).
            append(	"o_shippriority",		RandomValues.randomInt(1000, 1200)).
            append(	"o_comment", 			RandomValues.randomString(79));
			aOrders.add(oDocument);
		}
		
		return aOrders;
	}
	
	private List<BasicDBObject> _getCustomers() {
		List<BasicDBObject> aCustomers = new ArrayList<BasicDBObject>();
		/*C_CUSTKEY
		C_NAME variable text, size 25
		C_ADDRESS variable text, size 40
		C_NATIONKEY Identifier Foreign Key to N_NATIONKEY
		C_PHONE fixed text, size 15
		C_ACCTBAL Decimal
		C_MKTSEGMENT fixed text, size 10
		C_COMMENT variable text, size 117*/
		for (int i = 0; i < this.nInsertsCustomerExpected; i++) {
			BasicDBObject oDocument = new BasicDBObject(
					"c_custkey", 		i + 1).
            append(	"c_name", 			RandomValues.randomString(25)).
            append(	"c_address", 		RandomValues.randomString(40)).
            append(	"c_nationkey",		RandomValues.randomInt(1000, 9999)).
            append(	"c_phone", 			RandomValues.randomString(15)).
            append(	"c_acctbal", 		RandomValues.randomFloat(1000, 9999, 2)).
            append(	"c_mktsegment", 	RandomValues.randomString(10)).
            append(	"c_comment",		RandomValues.randomString(117));
			aCustomers.add(oDocument);
		}
		return aCustomers;
	}

}
